package com.dms.modules.product.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dms.common.api.ApiResponse;
import com.dms.common.security.SecurityUtils;
import com.dms.modules.product.dto.ProductSearchDTO;
import com.dms.modules.product.entity.Product;
import com.dms.modules.product.service.ProductService;
import com.dms.modules.user.service.UserBehaviorService;
import com.dms.modules.product.vo.ProductDetailVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Min;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 商品搜索控制器
 * 按角色分离搜索功能
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/products/search")
@Api(tags = "商品搜索接口")
@RequiredArgsConstructor
@Validated
public class ProductSearchController extends BaseProductController {

    private final ProductService productService;
    private final UserBehaviorService userBehaviorService;

    /* ---------- 公共搜索接口（不需要登录） ---------- */

    @GetMapping("/simple")
    @ApiOperation("简单搜索商品")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "keyword", value = "关键词", required = true, dataType = "String"),
        @ApiImplicitParam(name = "pageNum", value = "页码", defaultValue = "1", dataType = "Integer"),
        @ApiImplicitParam(name = "pageSize", value = "每页数量", defaultValue = "10", dataType = "Integer")
    })
    public ApiResponse<Page<Product>> simpleSearch(
            @RequestParam @NotBlank(message = "关键词不能为空") String keyword,
            @RequestParam(defaultValue = "1") @Min(value = 1, message = "页码不能小于1") Integer pageNum,
            @RequestParam(defaultValue = "10") @Min(value = 1, message = "每页条数不能小于1") Integer pageSize) {
        try {
            // 如果用户已登录，记录搜索行为
            if (SecurityUtils.isAuthenticated()) {
                Long userId = getUserId();
                if (userId != null) {
                    userBehaviorService.recordUserSearch(userId, keyword);
                }
            }
            
            ProductSearchDTO searchDTO = new ProductSearchDTO();
            searchDTO.setKeyword(keyword);
            searchDTO.setPageNum(pageNum);
            searchDTO.setPageSize(pageSize);
            IPage<Product> iPage = productService.search(searchDTO);
            Page<Product> page = convertIPageToPage(iPage);
            return ApiResponse.success(page);
        } catch (Exception e) {
            log.error("简单搜索商品失败: keyword={}", keyword, e);
            return ApiResponse.error("搜索商品失败");
        }
    }

    @PostMapping("/advanced")
    @ApiOperation("高级搜索商品")
    public ApiResponse<IPage<Product>> advancedSearch(@RequestBody @Validated ProductSearchDTO searchDTO) {
        try {
            // 如果用户已登录，记录搜索行为
            if (SecurityUtils.isAuthenticated() && searchDTO.getKeyword() != null && !searchDTO.getKeyword().isEmpty()) {
                Long userId = getUserId();
                if (userId != null) {
                    userBehaviorService.recordUserSearch(userId, searchDTO.getKeyword());
                }
            }
            
            IPage<Product> result = productService.search(searchDTO);
            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("高级搜索商品失败: searchDTO={}", searchDTO, e);
            return ApiResponse.error("搜索商品失败");
        }
    }

    @GetMapping("/hot")
    @ApiOperation("获取热门商品")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "categoryId", value = "分类ID", required = false, dataType = "Long"),
        @ApiImplicitParam(name = "limit", value = "返回数量", defaultValue = "10", dataType = "Integer")
    })
    public ApiResponse<List<ProductDetailVO>> getHotProducts(
            @RequestParam(required = false) Long categoryId,
            @RequestParam(defaultValue = "10") @Min(value = 1, message = "数量不能小于1") Integer limit) {
        try {
            List<ProductDetailVO> hotProducts = productService.getHotProducts(limit);
            return ApiResponse.success(hotProducts);
        } catch (Exception e) {
            log.error("获取热门商品失败", e);
            return ApiResponse.error("获取热门商品失败");
        }
    }

    @GetMapping("/new")
    @ApiOperation("获取新品列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "categoryId", value = "分类ID", required = false, dataType = "Long"),
        @ApiImplicitParam(name = "limit", value = "返回数量", defaultValue = "10", dataType = "Integer")
    })
    public ApiResponse<List<ProductDetailVO>> getNewProducts(
            @RequestParam(required = false) Long categoryId,
            @RequestParam(defaultValue = "10") @Min(value = 1, message = "数量不能小于1") Integer limit) {
        try {
            List<ProductDetailVO> newProducts = productService.getNewProducts(limit);
            return ApiResponse.success(newProducts);
        } catch (Exception e) {
            log.error("获取新品列表失败", e);
            return ApiResponse.error("获取新品列表失败");
        }
    }

    @GetMapping("/suggestions")
    @ApiOperation("获取搜索建议")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "keyword", value = "关键词", required = true, dataType = "String"),
        @ApiImplicitParam(name = "limit", value = "返回数量", defaultValue = "10", dataType = "Integer")
    })
    public ApiResponse<List<String>> getSearchSuggestions(
            @RequestParam @NotBlank(message = "关键词不能为空") String keyword,
            @RequestParam(defaultValue = "10") @Min(value = 1, message = "数量不能小于1") Integer limit) {
        try {
            List<String> suggestions = productService.getSearchSuggestions(keyword, limit);
            return ApiResponse.success(suggestions);
        } catch (Exception e) {
            log.error("获取搜索建议失败: keyword={}", keyword, e);
            return ApiResponse.error("获取搜索建议失败");
        }
    }

    /* ---------- 用户专属搜索接口 ---------- */

    @GetMapping("/history")
    @ApiOperation("获取搜索历史")
    @PreAuthorize("isAuthenticated()")
    @ApiImplicitParam(name = "limit", value = "返回数量", defaultValue = "10", dataType = "Integer")
    public ApiResponse<List<String>> getSearchHistory(
            @RequestParam(defaultValue = "10") @Min(value = 1) @Max(value = 50) Integer limit) {
        try {
            Long userId = getUserId();
            List<String> history = userBehaviorService.getUserRecentSearches(userId, limit);
            return ApiResponse.success(history);
        } catch (Exception e) {
            log.error("获取搜索历史失败", e);
            return ApiResponse.error("获取搜索历史失败");
        }
    }

    @DeleteMapping("/history")
    @ApiOperation("清除搜索历史")
    @PreAuthorize("isAuthenticated()")
    public ApiResponse<Void> clearSearchHistory() {
        try {
            Long userId = getUserId();
            userBehaviorService.clearUserSearchHistory(userId);
            return ApiResponse.success(null);
        } catch (Exception e) {
            log.error("清除搜索历史失败", e);
            return ApiResponse.error("清除搜索历史失败");
        }
    }

    /* ---------- 商家专属搜索接口 ---------- */

    @GetMapping("/merchant/products")
    @ApiOperation("商家搜索自己的商品")
    @PreAuthorize("hasRole('MERCHANT')")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "keyword", value = "关键词", required = false, dataType = "String"),
        @ApiImplicitParam(name = "status", value = "商品状态", required = false, dataType = "Integer"),
        @ApiImplicitParam(name = "categoryId", value = "分类ID", required = false, dataType = "Long"),
        @ApiImplicitParam(name = "pageNum", value = "页码", defaultValue = "1", dataType = "Integer"),
        @ApiImplicitParam(name = "pageSize", value = "每页数量", defaultValue = "10", dataType = "Integer")
    })
    public ApiResponse<Page<Product>> merchantSearchProducts(
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) Long categoryId,
            @RequestParam(defaultValue = "1") @Min(value = 1, message = "页码不能小于1") Integer pageNum,
            @RequestParam(defaultValue = "10") @Min(value = 1, message = "每页条数不能小于1") Integer pageSize) {
        try {
            Long merchantId = getUserId();
            ProductSearchDTO searchDTO = new ProductSearchDTO();
            searchDTO.setKeyword(keyword);
            searchDTO.setCategoryId(categoryId);
            searchDTO.setMerchantId(merchantId);
            searchDTO.setPageNum(pageNum);
            searchDTO.setPageSize(pageSize);
            
            // 特殊处理状态
            if (status != null) {
                // 假设我们有一个自定义的搜索方法来处理状态过滤
                IPage<Product> result = productService.searchMerchantProducts(searchDTO, status);
                return ApiResponse.success(convertIPageToPage(result));
            } else {
                IPage<Product> result = productService.search(searchDTO);
                return ApiResponse.success(convertIPageToPage(result));
            }
        } catch (Exception e) {
            log.error("商家搜索商品失败: keyword={}, status={}, categoryId={}", keyword, status, categoryId, e);
            return ApiResponse.error("搜索商品失败");
        }
    }

    /* ---------- 管理员专属搜索接口 ---------- */

    @PostMapping("/admin/advanced")
    @ApiOperation("管理员高级搜索商品(包含审核状态)")
    @PreAuthorize("hasRole('ADMIN')")
    public ApiResponse<IPage<Product>> adminAdvancedSearch(
            @RequestBody @Validated ProductSearchDTO searchDTO,
            @ApiParam("审核状态：0-待审核，1-通过，2-拒绝") @RequestParam(required = false) Integer auditStatus) {
        try {
            if (auditStatus != null) {
                // 假设我们有一个自定义的管理员搜索方法
                IPage<Product> result = productService.adminSearchProducts(searchDTO, auditStatus);
                return ApiResponse.success(result);
            } else {
                IPage<Product> result = productService.search(searchDTO);
                return ApiResponse.success(result);
            }
        } catch (Exception e) {
            log.error("管理员高级搜索商品失败", e);
            return ApiResponse.error("高级搜索商品失败");
        }
    }

    @GetMapping("/admin/audit-pending")
    @ApiOperation("获取待审核商品列表")
    @PreAuthorize("hasRole('ADMIN')")
    public ApiResponse<Page<Product>> getAuditPendingProducts(
            @RequestParam(defaultValue = "1") @Min(value = 1, message = "页码不能小于1") Integer pageNum,
            @RequestParam(defaultValue = "10") @Min(value = 1, message = "每页条数不能小于1") Integer pageSize) {
        try {
            // 假设我们有一个获取待审核商品的方法
            IPage<Product> iPage = productService.getAuditPendingProducts(pageNum, pageSize);
            Page<Product> page = convertIPageToPage(iPage);
            return ApiResponse.success(page);
        } catch (Exception e) {
            log.error("获取待审核商品列表失败", e);
            return ApiResponse.error("获取待审核商品列表失败");
        }
    }

    /**
     * 将IPage转换为Page
     */
    private <T> Page<T> convertIPageToPage(IPage<T> iPage) {
        if (iPage == null) {
            return null;
        }
        Page<T> page = new Page<>(iPage.getCurrent(), iPage.getSize(), iPage.getTotal());
        page.setRecords(iPage.getRecords());
        return page;
    }
} 